package com.nova.android.tvlauncher.download

import android.content.pm.PackageInstaller
import android.os.Handler
import android.os.Looper
import com.nova.android.tvlauncher.apkinstall.installMyXapkWithMutex
import com.nova.android.tvlauncher.apkinstall.uninstallMyApp
import com.nova.android.tvlauncher.download.AppTaskMarker.markDownloadCompleted
import com.nova.android.tvlauncher.download.AppTaskMarker.markDownloading
import com.nova.android.tvlauncher.download.AppTaskMarker.markInstalled
import com.nova.android.tvlauncher.download.AppTaskMarker.markInstalling
import com.nova.android.tvlauncher.download.AppTaskMarker.markPending
import com.nova.android.tvlauncher.download.AppTaskMarker.markUninstalling
import com.nova.android.tvlauncher.ext.localCheck
import com_github_lib_base.ext.isRepeatExcute
import io.github.lib_autorun.net.NetworkHelper
import io.github.lib_autorun.net.NetworkHelper.downloadFile
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import java.io.File
import java.util.concurrent.ConcurrentHashMap

/**
 * 应用下载与安装管理器
 * 提供下载、安装、卸载任务的统一入口和状态管理
 */
object AppDownloader {

    // IO作用域协程，用于执行下载/安装任务，SupervisorJob 确保异常不影响整体任务
    private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())

    // 所有任务状态的容器：key = businessId，value = 可观察状态流
    val tasks = ConcurrentHashMap<String, MutableStateFlow<AppTask>>()

    // 主线程 Handler，用于执行 UI 或与 UI 相关的延迟逻辑
    val handler = Handler(Looper.getMainLooper())

    // 当前的安装或卸载协程任务容器：key = businessId，value = Job
    val installJobs = ConcurrentHashMap<String, Job>()

    /**
     * 获取指定任务的状态流，如果不存在则自动创建
     * @param item 下载任务对象（传入已有 AppTask）
     */
    fun getTaskStatus(item: AppTask): StateFlow<AppTask>? {
        val businessId = item.businessId
        val filePath = item.filePath

        // 如果已有任务，执行本地校验后直接返回
        if (tasks[businessId] != null) return tasks[businessId]?.localCheck()

        // 创建新的任务并加入 tasks 映射
        val newTask = AppTask(
            businessId = businessId,
            url = item.url,
            filePath = filePath,
            status = AppTaskStatus.PENDING,
            versionCode = item.versionCode
        )

        val task = MutableStateFlow(newTask).localCheck()
        tasks[businessId] = task
        return task
    }

    /**
     * 开始下载指定应用任务（可重复调用）
     * @param item 要下载的应用任务
     * @return businessId
     */
    fun startDownload(item: AppTask): String {
        val businessId = item.businessId
        val url = item.url
        val versionCode = item.versionCode
        val filePath = item.filePath

        // 若任务不存在则创建
        val taskFlow = tasks[businessId]
        if (taskFlow == null) {
            val task = AppTask(businessId, url, filePath, versionCode = versionCode)
            tasks[businessId] = MutableStateFlow(task)
        }

        // 标记任务为下载中
        markDownloading(businessId)

        // 执行下载操作
        downloadFile(
            url,
            File(filePath),
            progressListener = { progress ->
                // 限制频繁更新
                if (progress != 100 && !isRepeatExcute(300)) {
                    markDownloading(businessId, progress.toFloat())
                }
            },
            callback = { success, error ->
                if (error == null) {
                    // 下载成功
                    markDownloadCompleted(businessId)

                    // 延迟 100ms 启动安装流程
                    handler.postDelayed({
                        installApp(businessId)
                    }, 100)
                } else {
                    println("当前下载失败的原因是：${error.message}")
                    markPending(item, 1)//下载失败，重置为等待状态
                }
            }
        )

        return businessId
    }

    /**
     * 取消下载任务
     * @param businessId 任务ID
     * @param url 下载链接
     */
    fun cancelDownload(businessId: String, url: String) {
        NetworkHelper.cancelDownload(url)  // 停止网络请求
        markPending(tasks[businessId]!!.value) // 重置任务状态
    }

    /**
     * 安装应用流程（支持失败处理和回退）
     * @param businessId 应用包名
     */
    fun installApp(businessId: String) {
        markInstalling(businessId)
        val task = tasks[businessId]?.value
        if(task==null)return
        installJobs[businessId]?.cancel()
        installJobs[businessId] = scope.launch {
            //println("准备安装的APK的路径是----${task.filePath}")
            val result = task.filePath.installMyXapkWithMutex()
           //println("当前的安装结果：${result.status}")
            when (result.status) {
                PackageInstaller.STATUS_SUCCESS -> {
                    markInstalled(task) // 安装成功
                }

                PackageInstaller.STATUS_FAILURE_ABORTED -> {
                    markDownloadCompleted(businessId) // 安装被用户取消
                }

                else -> {
                    markPending(task, 2) // 安装失败，回退为等待状态
                }
            }
        }
    }

    /**
     * 卸载应用流程（支持失败处理和回退）
     * @param businessId 应用包名
     */
    fun uninstallApp(businessId: String) {
        markUninstalling(businessId)
        installJobs[businessId]?.cancel()

        installJobs[businessId] = scope.launch {
            val result = businessId.uninstallMyApp()
            when (result.status) {
                PackageInstaller.STATUS_SUCCESS -> {
                    markPending(tasks[businessId]!!.value) // 卸载成功
                }

                PackageInstaller.STATUS_FAILURE_ABORTED->{
                    markInstalled(tasks[businessId]!!.value, 1) // 取消卸载，回退为已安装

                }
                else -> {
                    markInstalled(tasks[businessId]!!.value, 2) // 卸载失败，回退为已安装
                }
            }
        }
    }

    /**
     * 重置回默认pending状态
     * @param businessId 应用包名
     */
    fun resetPendingStatus(businessId: String) {
        markPending(tasks[businessId]!!.value)
    }

    /**
     * 重置回默认installed状态
     * @param businessId 应用包名
     */
    fun resetInstalledStatus(businessId: String) {
        markInstalled(tasks[businessId]!!.value)
    }

    /**
     * 清理任务：从内存中移除
     * @param businessId 任务ID
     */
    private fun clearTask(businessId: String) {
        tasks.remove(businessId)
    }
}
